package zcatt.examples.jface.snippets;

import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class Snippet007PopupDialog extends ApplicationWindow {

	public static void main(String[] args) {
		Display display = new Display();
		
		ApplicationWindow appWin = new Snippet007PopupDialog();
		appWin.setBlockOnOpen(true);
		appWin.open();
		
		display.dispose();
	}
	
	
	InfoPopupDialog infoPopupDialog;
	
	public Snippet007PopupDialog() {
		super(null);
	}

	@Override
	public boolean close() {
		
		if(infoPopupDialog != null)
			infoPopupDialog.close();
	
		return super.close();
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		shell.setText("Snippet007PopupDialog");
	}

	@Override
	protected Control createContents(Composite parent) {
		Composite comp = new Composite(parent, SWT.NONE);
		comp.setLayout(new GridLayout());
		
		Button btn;
		btn = new Button(comp, SWT.PUSH);
		btn.setText("InfoPopupDialog");
		btn.addSelectionListener(SelectionListener.widgetSelectedAdapter(event->{
			if(infoPopupDialog == null)
			{
				infoPopupDialog = new InfoPopupDialog(getShell());
				infoPopupDialog.open();
				infoPopupDialog.getShell().addDisposeListener(evt -> infoPopupDialog = null);				
			}
			else
			{
				//infoPopupDialog.getShell().setFocus();
				infoPopupDialog.close();
			}
		}));

		return comp;
	}
	
	
	
	
	
	class InfoPopupDialog extends PopupDialog {
		
		private Text text;

		InfoPopupDialog(Shell parent) {
			super(parent, PopupDialog.HOVER_SHELLSTYLE, false, false, false,
					false, false, null, null);
		}

		/*
		 * Create a text control for showing the info about a proposal.
		 */
		@Override
		protected Control createDialogArea(Composite parent) {
			text = new Text(parent, SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.NO_FOCUS);

			// Use the compact margins employed by PopupDialog.
			GridData gd = new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
			gd.horizontalIndent = PopupDialog.POPUP_HORIZONTALSPACING;
			gd.verticalIndent = PopupDialog.POPUP_VERTICALSPACING;
			text.setLayoutData(gd);
			text.setText("This is a InfoPopupDialog. autoClose when lostFocus");

			getShell().addShellListener(ShellListener.shellActivatedAdapter(event->{
				System.out.println("activated");				
			}));

			getShell().addShellListener(ShellListener.shellDeactivatedAdapter(event->{
				System.out.println("deactivated");				
			}));
			
			// since SWT.NO_FOCUS is only a hint...
			text.addFocusListener(new FocusAdapter() {
				
				@Override
				public void focusGained(FocusEvent e) {
					System.out.println("gain focus.");
					close();
				}

				@Override
				public void focusLost(FocusEvent event) {
					System.out.println("lost focus.");
				}
			});
			
			//text.addMouseListener(MouseListener.mouseDownAdapter(event->close()));
			
			return text;
		}
			
		/*
		 * Adjust the bounds so that we appear adjacent to our parent shell
		 */
		@Override
		protected void adjustBounds() {
			Rectangle parentBounds = getParentShell().getBounds();
			Rectangle proposedBounds;
			// Try placing the info popup to the right
			Rectangle rightProposedBounds = new Rectangle(parentBounds.x
					+ parentBounds.width
					+ PopupDialog.POPUP_HORIZONTALSPACING, parentBounds.y
					+ PopupDialog.POPUP_VERTICALSPACING,
					parentBounds.width, parentBounds.height);
			rightProposedBounds = getConstrainedShellBounds(rightProposedBounds);
			// If it won't fit on the right, try the left
			if (rightProposedBounds.intersects(parentBounds)) {
				Rectangle leftProposedBounds = new Rectangle(parentBounds.x
						- parentBounds.width - POPUP_HORIZONTALSPACING - 1,
						parentBounds.y, parentBounds.width,
						parentBounds.height);
				leftProposedBounds = getConstrainedShellBounds(leftProposedBounds);
				// If it won't fit on the left, choose the proposed bounds
				// that fits the best
				if (leftProposedBounds.intersects(parentBounds)) {
					if (rightProposedBounds.x - parentBounds.x >= parentBounds.x
							- leftProposedBounds.x) {
						rightProposedBounds.x = parentBounds.x
								+ parentBounds.width
								+ PopupDialog.POPUP_HORIZONTALSPACING;
						proposedBounds = rightProposedBounds;
					} else {
						leftProposedBounds.width = parentBounds.x
								- POPUP_HORIZONTALSPACING
								- leftProposedBounds.x;
						proposedBounds = leftProposedBounds;
					}
				} else {
					// use the proposed bounds on the left
					proposedBounds = leftProposedBounds;
				}
			} else {
				// use the proposed bounds on the right
				proposedBounds = rightProposedBounds;
			}
			getShell().setBounds(proposedBounds);
		}

		@Override
		protected Color getForeground() {
			return getShell().getDisplay().
					getSystemColor(SWT.COLOR_INFO_FOREGROUND);
		}

		@Override
		protected Color getBackground() {
			return getShell().getDisplay().
					getSystemColor(SWT.COLOR_INFO_BACKGROUND);
		}

		/*
		 * Set the text contents of the popup.
		 */
		void setContents(String newContents) {
			if (newContents == null) {
				newContents = "";
			}

			if (text != null && !text.isDisposed()) {
				text.setText(newContents);
			}
		}

		/*
		 * Return whether the popup has focus.
		 */
		boolean hasFocus() {
			if (text == null || text.isDisposed()) {
				return false;
			}
			return text.getShell().isFocusControl()
					|| text.isFocusControl();
		}	
		
	}

}
